#pragma once
#include <cstdint>
#include <cstddef>
#include <chrono>
#include <utility>
#include "particle.hpp"

// 初始化：将同一份随机数据写入 AoS 与 SoA（含 mass）
void init_particles(std::vector<ParticleAoS>& aos,
                    ParticlesSoA& soa,
                    std::uint64_t seed = 42,
                    float lo = -1.0f, float hi = 1.0f);

// 基准：AoS/SoA，返回校验和（含 mass），新增 e、f 控制 mass 更新
float bench_aos(std::vector<ParticleAoS>& aos,
                int iters,
                float a, float b, float c, float d,
                double e, double f);

float bench_soa(ParticlesSoA& soa,
                int iters,
                float a, float b, float c, float d,
                double e, double f);

// 计时工具：对可调用对象进行多次测量，返回最佳毫秒数
template <class F>
double timeit(F&& f, int warmup = 1, int repeat = 5) {
    for (int i = 0; i < warmup; ++i) {
        volatile float guard = f();
        (void)guard;
    }
    double best = 1e300;
    for (int i = 0; i < repeat; ++i) {
        auto t0 = std::chrono::high_resolution_clock::now();
        volatile float guard = f();
        (void)guard;
        auto t1 = std::chrono::high_resolution_clock::now();
        double ms = std::chrono::duration<double, std::milli>(t1 - t0).count();
        if (ms < best) best = ms;
    }
    return best;
}